const add = (x,y) =>  x + y
const square = (x) => x * x

// const res = square( add(1,2))
// console.log(res)

const compose = (fn1,fn2) => {
    return (...args) => {
       return fn2(fn1(...args))
    }
}

// const composeFn = compose(add,square)
// console.log(composeFn(1,2))

//通过...[first,...other] 把数组解构成  能索引第一个和后面新数组的结构
const composeMore = (...[first,...other]) => (...args) => {
    let ret = first(...args)//第一个方法先执行一遍
    other.forEach( (fn) => {//按顺序从第二个开始执行方法
        ret = fn(ret)//传入参数是全局的上一次结果
    })
    return ret;
}


// const composeMoreFn = composeMore(add,square)
// console.log(composeMoreFn(1,2))


// const compose = (...[first,...other]) => (...args) => {
//     let ret = first(...args)
//     other.forEach(fn => {
//         ret = fn(ret)
//     })
//     return ret
// }



// function composePromise(middlewares) {
//     console.log("composePromise")
//     return function () {//这里定义方法形式，而不是立刻执行,留给业务代码执行
//         return dispatch(0);//从第一个方法开始执行
//         function dispatch(i) { //结果一定返回一个promies 成功对象
//             let fn = middlewares[i];
//             console.log("i",i,fn)
//             if(!fn){//处理 下面代码dispatch(i + 1) 最后一个是多+1 ，不存在的fn的情况  不是函数的情况 
//                 return Promise.resolve(); //对应的执行代码为： await next()方法
//             }
//             return Promise.resolve(  
//                 fn( function next() {//这里定义方法形式，而不是立刻执行,留给业务代码执行
//                     return dispatch(i + 1)//传入下一个数组对象的方法，并返回Promise对象
//                 })
//             )
//         }
//     }
// }
// //测试代码

// async function fn1(next){
//     console.log('fn1')
//     await next()
//     console.log('end fn1')
// }

// async function fn2(next){
//     console.log('fn2')
//     await delay()
//     await next()
//     console.log('end fn2')
// }

// function fn3(next){
//     console.log('fn3')
// }

// function delay(){
//     return Promise.resolve(res => {
//         setTimeout(() => reslove(),2000)
//     })
// }

// const middlewares = [fn1,fn2,fn3]
// const finalFn = composePromise(middlewares)
// finalFn()


